﻿#region Copyright ©2008-2010, Technische Universitaet Muenchen
// ====================================================================================================
//
// Last Changed by       $Author: then $
// Last Changed Date     $LastChangedDate: 2009-06-15 08:45:45 +0200 (Mon, 15 Jun 2009) $
// Last Changed Revision $Rev: 194 $
//
// ====================================================================================================
#endregion

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace Tum.CollabXT.Wizard
{
    /// <summary>
    /// A conversion project.
    /// </summary>
    internal class ConversionProject
    {
        /// <summary>
        /// Project file of the current project.
        /// </summary>
        string ProjectFile;

        /// <summary>
        /// Gets or sets the used process provider.
        /// </summary>
        public ProcessProviderInfo ProcessProvider
        {
            get { return _ProcessProvider; }
            set { _ProcessProvider = value; }
        }
        ProcessProviderInfo _ProcessProvider;

        /// <summary>
        /// Gets a list of the tool providers, which will be used.
        /// </summary>
        public List<ToolProviderInfo> ToolProviders
        {
            get { return _ToolProviders; }
        }
        List<ToolProviderInfo> _ToolProviders = new List<ToolProviderInfo>();


        /// <summary>
        /// Constructor.
        /// </summary>
        public ConversionProject()
        { }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="projectFile">Project file to be loaded.</param>
        /// <param name="pluginManager">Plugin manager to be used.</param>
        public ConversionProject(string projectFile, PluginManager pluginManager)
        {
            if (!File.Exists(projectFile))
                throw new CxtWizardException("Project file does not exist");

            ProjectFile = projectFile;
            Load(pluginManager);
        }

        /// <summary>
        /// Load the current project from a project file.
        /// </summary>
        /// <param name="pluginManager">Plugin manager to be used.</param>
        private void Load(PluginManager pluginManager)
        {
            using(XmlReader xmlReader = XmlReader.Create(ProjectFile))
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlReader);

                XmlNode projectNode = xmlDoc.SelectSingleNode("PETproject");
                if (projectNode == null)
                    projectNode = xmlDoc.SelectSingleNode("CollabXTproject"); //Legacy compatibility
                if (projectNode != null)
                {
                    XmlNode processProviderNode = projectNode.SelectSingleNode("processprovider");
                    if (processProviderNode != null)
                    {
                        XmlNode pluginNode = processProviderNode.Attributes["plugin"];
                        if (pluginNode != null)
                        {
                            string pluginFile = pluginNode.Value;
                            foreach (ProcessProviderInfo curPp in pluginManager.GetProcessProviders())
                            {
                                if (Helper.FileNameFromPath(curPp.AssemblyPath).Equals(pluginFile, StringComparison.OrdinalIgnoreCase))
                                {
                                    ProcessProvider = curPp;
                                    try
                                    {
                                        curPp.Instance.Deserialize(processProviderNode);
                                    }
                                    catch (Exception)
                                    {
                                    }
                                    break;
                                }
                            }
                        }
                    }

                    XmlNode toolProvidersNode = projectNode.SelectSingleNode("toolproviders");
                    if (toolProvidersNode != null)
                    {
                        XmlNodeList tpNodes = toolProvidersNode.SelectNodes("toolprovider");
                        foreach (XmlNode curTPNode in tpNodes)
                        {
                            string pluginFile = curTPNode.Attributes["plugin"].Value;
                            foreach (ToolProviderInfo curTP in pluginManager.GetToolProviders())
                            {
                                if (Helper.FileNameFromPath(curTP.AssemblyPath).Equals(pluginFile, StringComparison.OrdinalIgnoreCase))
                                {
                                    ToolProviders.Add(curTP);
                                    try
                                    {
                                        curTP.Instance.Deserialize(curTPNode);
                                    }
                                    catch (Exception) { }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Saves the current project to a project file.
        /// </summary>
        /// <param name="outputFile">Output project file path and name.</param>
        public void Save(string outputFile)
        {
            if(ProjectFile == null && (outputFile == null || outputFile.Length == 0))
                throw new CxtWizardException("You must specify an output file.");

            if(outputFile != null)
                ProjectFile = outputFile;

            //Create file
            using (XmlWriter xmlWriter = XmlWriter.Create(ProjectFile))
            {
                XmlDocument xmlDoc = new XmlDocument();

                //Main node
                XmlNode projectNode = xmlDoc.CreateElement("PETproject");
                xmlDoc.AppendChild(projectNode);

                #region Write process provider
                if (ProcessProvider != null)
                {
                    XmlNode processProviderNode = xmlDoc.CreateElement("processprovider");
                    projectNode.AppendChild(processProviderNode);

                    XmlAttribute ppPathAttribute = xmlDoc.CreateAttribute("plugin");
                    ppPathAttribute.Value = Helper.FileNameFromPath(ProcessProvider.AssemblyPath);
                    processProviderNode.Attributes.Append(ppPathAttribute);

                    try
                    {
                        ProcessProvider.Instance.Serialize(processProviderNode);
                    }
                    catch (Exception) { }
                }
                #endregion


                #region Save tool providers
                XmlNode toolProvidersNode = xmlDoc.CreateElement("toolproviders");
                projectNode.AppendChild(toolProvidersNode);

                foreach (ToolProviderInfo curToolProvider in ToolProviders)
                {
                    XmlNode curToolProviderNode = xmlDoc.CreateElement("toolprovider");
                    toolProvidersNode.AppendChild(curToolProviderNode);

                    XmlAttribute tpPathAttribute = xmlDoc.CreateAttribute("plugin");
                    tpPathAttribute.Value = Helper.FileNameFromPath(curToolProvider.AssemblyPath);
                    curToolProviderNode.Attributes.Append(tpPathAttribute);

                    try
                    {
                        curToolProvider.Instance.Serialize(curToolProviderNode);
                    }
                    catch (Exception) { }
                }
                #endregion


                //Close file
                xmlDoc.Save(xmlWriter);
            }
        }
    }
}